package cs2340.spring13.team3.wheresmystuff.views;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.codehaus.jackson.JsonParseException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.RadioGroup;

import com.loiane.util.JsonDateSerializer;

import cs2340.spring13.team3.wheresmystuff.R;
import cs2340.spring13.team3.wheresmystuff.model.Item;
import cs2340.spring13.team3.wheresmystuff.model.Tag;
import cs2340.spring13.team3.wheresmystuff.model.User;
import cs2340.spring13.team3.wheresmystuff.presenters.LoginManager;

/**
 * This class presents the view for the user to add one lost item, including the
 * item's name, description and tags.
 * 
 * @author carmen78xy
 * 
 */
public class AddItemActivity extends Activity {

	private User currentUser;
	private EditText mItemNameView;
	private EditText mItemRewardView;
	private EditText mItemDescriptionView;
	private EditText mItemDateView;
	private RadioGroup mLostOrFound;
	private EditText mTagsView;

	private String itemName;
	private double itemReward;
	private String itemDescription;
	private boolean isLost = true;
	private String itemDate;

	private CreateItemTask mAddTask;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		currentUser = LoginManager.getInstance().getUser();
		setContentView(R.layout.activity_add_item);
		setupActionBar();

		mItemNameView = (EditText) findViewById(R.id.item_name_text);
		mItemRewardView = (EditText) findViewById(R.id.item_reward_text);
		mItemDateView = (EditText) findViewById(R.id.item_date_text);
		mItemDescriptionView = (EditText) findViewById(R.id.item_description_text);
		mLostOrFound = (RadioGroup) findViewById(R.id.lost_or_found);
		mTagsView = (EditText) findViewById(R.id.add_tags_text);

		findViewById(R.id.add_btn).setOnClickListener(
				new View.OnClickListener() {
					@Override
					public void onClick(View view) {
						onAddItemClick(view);
					}
				});
		findViewById(R.id.cancel_btn).setOnClickListener(
				new View.OnClickListener() {
					@Override
					public void onClick(View v) {
						advance();
					}
				});

	}

	private void setupActionBar() {

		getActionBar().setDisplayHomeAsUpEnabled(true);

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.add_item, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			// This ID represents the Home or Up button. In the case of this
			// activity, the Up button is shown. Use NavUtils to allow users
			// to navigate up one level in the application structure. For
			// more details, see the Navigation pattern on Android Design:
			//
			// http://developer.android.com/design/patterns/navigation.html#up-vs-back
			//
			NavUtils.navigateUpFromSameTask(this);
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * Add the new item the user has entered to the user's lost items list.
	 * 
	 * @param view
	 */
	public void onAddItemClick(View view) {
		boolean valid = true;
		itemDate = mItemDateView.getText().toString();
		itemName = mItemNameView.getText().toString();
		itemDescription = mItemDescriptionView.getText().toString();
		String itemTags = mTagsView.getText().toString();
		Matcher m = Pattern
				.compile(
						"((?:(?:19)|(?:20))\\d\\d)[-/]((?:0?\\d)|(?:1[012]))[-/]((?:0?\\d)|(?:[12]\\d)|(?:3[01]))")
				.matcher(itemDate);
		if (itemName.length() == 0) {

			mItemNameView.setError("Please enter item name");
			valid = false;
		}
		if (itemDescription.length() == 0) {
			// AlertDialog alertDialog = new AlertDialog.Builder(this).create();
			// alertDialog.setTitle("Error");
			mItemDescriptionView.setError("Please enter item description");
			valid = false;
			// alertDialog.show();
			// return;
		}
		if (itemTags.length() == 0) {
			// AlertDialog alertDialog = new AlertDialog.Builder(this).create();
			// alertDialog.setTitle("Error");
			mTagsView.setError("Please enter tag(s) for your item");
			valid = false;
			// alertDialog.show();
			// return;
		}
		if (!m.matches()) {
			// AlertDialog alertDialog = new AlertDialog.Builder(this).create();
			// alertDialog.setTitle("Error");
			mItemDateView.setError("improperly formatted date string \""
					+ itemDate + "\". Please use format YYYY-MM-DD");
			valid = false;
			// alertDialog.show();
			// return;
		}
		if (valid) {
			Date inputDate = null;
			try {
				inputDate = JsonDateSerializer.DATE_FORMAT.parse(m.group(1)
						+ "-" + m.group(2) + "-" + m.group(3));
			} catch (ParseException e) {
				AlertDialog alertDialog = new AlertDialog.Builder(this)
						.create();
				alertDialog.setTitle("Error");
				alertDialog.setMessage("Error Parsing date string \""
						+ m.group(0) + "\".");
				alertDialog.show();
				return;
			}
			String rewardString = mItemRewardView.getText().toString();
			if (rewardString.length() == 0) {
				itemReward = 0.0;
			} else {
				itemReward = Double.parseDouble(rewardString);
			}
			itemDescription = mItemDescriptionView.getText().toString();
			itemName = mItemNameView.getText().toString();

			switch (mLostOrFound.getCheckedRadioButtonId()) {
			case R.id.radio_found:
				isLost = false;
				break;
			default:
				isLost = true;
				break;
			}

			List<Tag> itemTagList = new ArrayList<Tag>();
			if (itemTags != null && itemTags.length() > 0) {
				String[] tags = itemTags.split(",");
				for (String tag : tags) {
					if (tag.length() > 0) {
						Tag newTag = new Tag();
						newTag.setTitle(tag);
						itemTagList.add(newTag);
					}
				}
			}

			if (mAddTask == null) {
				mAddTask = new CreateItemTask(this, itemName, itemDescription,
						itemReward, isLost, itemTagList, inputDate);
				mAddTask.execute((Void) null);
			}
		}

	}

	/**
	 * See {@link #advance()}
	 * 
	 * @param view
	 */
	public void onCancelClick(View ignored) {
		advance();
	}

	/**
	 * Goes back up to the ViewLostItemsActivity.
	 */
	public void advance() {
		NavUtils.navigateUpFromSameTask(this);

	}

	public static class DatePickerFragment extends DialogFragment implements
			DatePickerDialog.OnDateSetListener {

		@Override
		public Dialog onCreateDialog(Bundle savedInstanceState) {
			// Use the current date as the default date in the picker
			final Calendar c = Calendar.getInstance();
			int year = c.get(Calendar.YEAR);
			int month = c.get(Calendar.MONTH);
			int day = c.get(Calendar.DAY_OF_MONTH);

			// Create a new instance of DatePickerDialog and return it
			return new DatePickerDialog(getActivity(), this, year, month, day);
		}

		public void onDateSet(DatePicker view, int year, int month, int day) {
			// Do something with the date chosen by the user
			Calendar cal = Calendar.getInstance();
			cal.set(year, month, day);
			// itemDate = cal.getTime();
		}
	}

	/**
	 * Represents an asynchronous login/registration task used to authenticate
	 * the user.
	 */
	public class CreateItemTask extends AsyncTask<Void, Void, Boolean> {
		private Activity activity;
		private String name, description;
		private double reward;
		private boolean lost;
		private List<Tag> tags;
		private Item newItem;
		private Exception err;
		private boolean parseErr;
		private Date date;

		/**
		 * Create the item and sync it to the backend in the background
		 * 
		 * @param applicationActivity
		 * @param itemName
		 * @param itemDescription
		 * @param itemReward
		 * @param isLost
		 * @param itemTagList
		 */
		public CreateItemTask(Activity applicationActivity, String itemName,
				String itemDescription, double itemReward, boolean isLost,
				List<Tag> itemTagList, Date itemDate) {
			this.activity = applicationActivity;
			this.name = itemName;
			this.description = itemDescription;
			this.reward = itemReward;
			this.lost = isLost;
			this.tags = itemTagList;
			this.date = itemDate;
		}

		@Override
		protected Boolean doInBackground(Void... params) {
			try {
				this.newItem = new Item(name, description, reward, lost, tags,
						date);
				return true;
			} catch (JsonParseException e) {
				this.err = e;
				this.parseErr = true;
			} catch (IOException e) {
				this.err = e;
			}
			return false;
		}

		@Override
		protected void onPostExecute(final Boolean success) {
			mAddTask = null;
			if (success) {
				currentUser.addItem(this.newItem);
				try {
					advance();
				} catch (Exception e) {
					e.printStackTrace();
				}

			} else {
				if (this.err != null) {
					AlertDialog alertDialog = new AlertDialog.Builder(
							this.activity).create();
					alertDialog.setTitle("Error!");
					alertDialog.setMessage(this.err.getMessage());
					alertDialog.show();
					this.err.printStackTrace();
					if (this.parseErr) {
						alertDialog = new AlertDialog.Builder(this.activity)
								.create();
						alertDialog.setTitle("Location info");
						alertDialog.setMessage(((JsonParseException) this.err)
								.getLocation().toString());
						alertDialog.show();
					}
				}
			}
		}

		@Override
		protected void onCancelled() {
			mAddTask = null;
		}
	}
}
